/**
 * 
 */
package com.yishuifengxiao.common.security.extractor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;

import com.yishuifengxiao.common.security.SecurityProperties;
import com.yishuifengxiao.common.security.constant.TokenConstant;

/**
 * 系统信息提取器
 * 
 * @author yishui
 * @version 1.0.0
 * @since 1.0.0
 */
public class SimpleSecurityExtractor implements SecurityExtractor {

	public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
	public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";

	/**
	 * 配置属性
	 */
	private SecurityProperties securityProperties;

	/**
	 * 从请求中提取出用户的登陆账号
	 * 
	 * @param request  HttpServletRequest
	 * @param response HttpServletResponse
	 * @return 用户的登陆账号
	 */
	@Override
	public String extractUsername(HttpServletRequest request, HttpServletResponse response) {
		String usernameParameter = securityProperties.getCore().getUsernameParameter();
		if (StringUtils.isBlank(usernameParameter)) {
			usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
		}
		return request.getParameter(usernameParameter.trim());
	}

	/**
	 * 从请求中提取出用户的登陆密码
	 * 
	 * @param request  HttpServletRequest
	 * @param response HttpServletResponse
	 * @return 用户的登陆密码
	 */
	@Override
	public String extractPassword(HttpServletRequest request, HttpServletResponse response) {
		String passwordParameter = securityProperties.getCore().getPasswordParameter();
		if (StringUtils.isBlank(passwordParameter)) {
			passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
		}
		return request.getParameter(passwordParameter.trim());
	}

	/**
	 * 从请求中提取出用户的唯一标识符
	 * 
	 * @param request  HttpServletRequest
	 * @param response HttpServletResponse
	 * @return 用户的唯一标识符
	 */
	@Override
	public String extractUserUniqueIdentitier(HttpServletRequest request, HttpServletResponse response) {
		String identitierParamter = securityProperties.getToken().getUserUniqueIdentitier();
		if (StringUtils.isBlank(identitierParamter)) {
			identitierParamter = TokenConstant.USER_UNIQUE_IDENTIFIER;
		}
		String identitierValue = request.getHeader(identitierParamter);
		if (StringUtils.isBlank(identitierValue)) {
			identitierValue = request.getParameter(identitierParamter);
		}
		if (StringUtils.isBlank(identitierValue)) {
			if (BooleanUtils.isTrue(securityProperties.getToken().getUseSessionId())) {
				// 使用sessionId作为用户的唯一标识符
				identitierValue = request.getSession().getId();
			}
		}
		return identitierValue;
	}

	/**
	 * 从请求中提取出访问令牌信息
	 * 
	 * @param request  HttpServletRequest
	 * @param response HttpServletResponse
	 * @return 访问令牌信息
	 */
	@Override
	public String extractTokenValue(HttpServletRequest request, HttpServletResponse response) {
		String tokenValue = this.getTokenValueInHeader(request);
		if (StringUtils.isBlank(tokenValue)) {
			tokenValue = this.getTokenValueInQuery(request);
		}
		return tokenValue;
	}

	/**
	 * 从请求参数里获取tokenValue
	 * 
	 * @param request HttpServletRequest
	 * @return tokenValue
	 */
	private String getTokenValueInQuery(HttpServletRequest request) {
		String requestParamter = securityProperties.getToken().getRequestParamter();
		if (StringUtils.isBlank(requestParamter)) {
			requestParamter = TokenConstant.TOKEN_REQUEST_PARAM;
		}

		String tokenValue = request.getParameter(requestParamter);

		if (StringUtils.isBlank(tokenValue)) {
			tokenValue = (String) request.getSession().getAttribute(requestParamter);
		}
		return tokenValue;
	}

	/**
	 * 从请求头里获取到tokenValue
	 * 
	 * @param request HttpServletRequest
	 * @return tokenValue
	 */
	private String getTokenValueInHeader(HttpServletRequest request) {
		String headerParamter = securityProperties.getToken().getHeaderParamter();
		if (StringUtils.isBlank(headerParamter)) {
			headerParamter = TokenConstant.TOKEN_HEADER_PARAM;
		}
		return request.getHeader(headerParamter);
	}

	public SecurityProperties getSecurityProperties() {
		return securityProperties;
	}

	public void setSecurityProperties(SecurityProperties securityProperties) {
		this.securityProperties = securityProperties;
	}

}
